using MediatR;
using Microsoft.EntityFrameworkCore;
using Medical.Domain;
using Medical.ErrorCode;
using Medical.Infrastructrue.Interfaces;
using Medical.ReadApi.Appcontext.Command;
using Medical.ReadApi.Dto;

namespace Medical.ReadApi.Appcontext.CommandHandler
{
	public class GetUsersListQueryHandler : IRequestHandler<GetUsersListQuery, ApiPaging<UserDto>>
	{
		private readonly IBaseRepository<User> _userRepo;

		public GetUsersListQueryHandler(IBaseRepository<User> userRepo)
		{
			_userRepo = userRepo;
		}

		public async Task<ApiPaging<UserDto>> Handle(GetUsersListQuery request, CancellationToken cancellationToken)
		{
			var query = _userRepo.GetAll().Where(x => !x.IsDeleted);
			
			if (!string.IsNullOrEmpty(request.UserNameKeyword))
				query = query.Where(x => x.UserName.Contains(request.UserNameKeyword));
			
			if (!string.IsNullOrEmpty(request.FullNameKeyword))
				query = query.Where(x => x.FullName != null && x.FullName.Contains(request.FullNameKeyword));
			
			if (!string.IsNullOrEmpty(request.Email))
				query = query.Where(x => x.Email == request.Email);
			
			if (request.IsActive.HasValue)
				query = query.Where(x => x.IsActive == request.IsActive.Value);

			var totalCount = await query.CountAsync(cancellationToken);
			var items = await query
				.OrderByDescending(x => x.CreatedAt)
				.Skip((request.Page - 1) * request.Size)
				.Take(request.Size)
				.Select(u => new UserDto
				{
					UserId = u.UserId,
					UserName = u.UserName,
					Email = u.Email,
					FullName = u.FullName,
					Phone = u.Phone,
					EmployeeId = u.EmployeeId,
					IsActive = u.IsActive,
					LastLoginAt = u.LastLoginAt,
					LastLoginIp = u.LastLoginIp,
					CreatedAt = u.CreatedAt,
					UpdatedAt = u.UpdatedAt
				})
				.ToListAsync(cancellationToken);

			var totalPage = (int)Math.Ceiling(totalCount / (double)request.Size);
			return new ApiPaging<UserDto> { totalCount = totalCount, totalPage = totalPage, data = items };
		}
	}
}

